"""

在Python中，一个类可以生成无数个对象，当一个对象的方法被调用时，对象会将自身的引用作为第一个参数（即方法的self参数），传递给该方法。这样，Python就知道需要操作哪个对象的方法了。

带self参数的方法也称作实例方法，在类的实例方法中访问实例变量时，须以self为前缀，但在外部通过对象名调用实例方法时不需要传递该参数。

【例 6-2】   self参数的使用。
【参考代码】
"""

# class Person:  # 定义Person类
#     def named(self, name):  # 定义命名的方法
#         self.name = name  # 赋值
#
#     def speak(self):  # 定义显示名字的方法
#         print('我的名字是{}'.format(self.name))  # 输出名字
#
#
# xiaolan = Person()  # 创建对象xiaolan
# xiaolan.named('小蓝')  # xiaolan调用named()方法
#
# xiaowu = Person()  # 创建对象xiaowu
# xiaowu.named('小舞')  # xiaowu调用named()方法
#
# xiaolan.speak()  # xiaolan调用speak()方法
# xiaowu.speak()  # xiaowu调用speak()方法

"""
拓展：
    Python在类中定义方法时将第一个参数命名为self只是一个习惯，而实际上名称是可以改变的。例如：
       class A:
            def show(my):
            print('hello!')
       a = A()
       a.show()
    上述代码中，将show()方法的第一个参数命名为my，程序运行结果为“hello!”。
"""

"""
1、类方法，类属性，静态方法 都是通过类名去调用
2、实例属性、实例方法都是通过实例名去调用的
"""


class Student():
    # 类属性：直接定义在类中，方法外得变量
    school = '信息'

    # 实例属性：定义在__init__方法中，使用self打点得变量;  =左侧是实例属性，=右侧局部变量
    def __init__(self, name, age):  # name age 是方法的参数，是局部变量，作用域是__init__方法
        self.name = name
        self.age = age

    # 实例方法：定义在类中的函数，而且自带参数self
    def show(self):
        print(f'我叫：{self.name},今年{self.age}岁了')
        print(self.school)  # 实例方法可以直接访问类属性
        self.show2()  # 实例方法可以直接访问静态方法
        self.show3()  # 实例方法可以直接访问类方法

    # 静态方法:使用@staticmethod装饰器装饰的方法
    @staticmethod
    def show2():
        print(Student.school)  # 类得静态方法可以访问/操作 类属性
        # print(self.name)   #报错  静态方法不能访问实例属性
        # print(self.age)    #报错  静态方法不能访问实例属性
        print('这是一个静态方法,不能调用示例属性，也不能调用实例方法')

    # 类方法:使用@classmethod装饰器装饰的方法
    @classmethod
    def show3(cls):
        print(Student.school)  # 类得静态方法可以访问/操作 类属性
        # print(self.name)   #报错  静态方法不能访问实例属性
        # print(self.age)    #报错  静态方法不能访问实例属性
        print('这是一个类方法，不能调用示例属性，也不能调用实例方法')


# 访问类属性  (即使没有实例化对象，依旧可以通过类名进行访问)
print(Student.school)

# 访问类方法  (即使没有实例化对象，依旧可以通过类名进行访问)
Student.show3()

# 访问静态方法  (即使没有实例化对象，依旧可以通过类名进行访问)
Student.show2()

# 创建对象  === 实例化对象（拿类模板 实例化对象）
stu = Student('小明', 18)  # 实例化对象

# 实例属性访问
print(stu.name, stu.age)

# 实例方法访问
stu.show()
stu.__init__('小红', 16)  # 可以访问初始化函数
stu.show()
